import * as THREE from 'three';
import { ThreeRender } from '@/components/Warm/SDK/three';
// @ts-ignore

import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import vertexShader from './glsl/vertex.glsl?raw';
import fragmentShader from './glsl/fragment.glsl?raw';
import d from '@/assets/largeScreen/background.png';

type MusicConfigType = {
    isOpenGUI?: boolean,
    useCanvasHeightAndWidth?: boolean
}

export class Shader extends ThreeRender {

        private controls: OrbitControls;

        private material: THREE.ShaderMaterial | null = null;

    constructor(el: Element, config?: MusicConfigType) {
        super(el, { useCanvasHeightAndWidth: !!config?.useCanvasHeightAndWidth });
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.initShader();
        this.setLight();
        this.setControls();
        this.setCamera();
        this.animate();
    }

    private initShader() {
        this.material = new THREE.RawShaderMaterial({
            vertexShader: vertexShader,
            fragmentShader: fragmentShader,
            side: THREE.DoubleSide,
            wireframe: false,
            uniforms: {
                u_fade: { value: 0.0 },
                u_time: { value: 0.0 },
                u_color: { value: new THREE.Color(0xA1BFD7) },
                u_wind: { value: new THREE.Vector2(0.1, 0.1) },
                u_resolution: { value: new THREE.Vector2() },
                u_texture: { value: new THREE.TextureLoader().load(d) },
                u_frequency: { value: new THREE.Vector2(10, 5) }
            }
        });

        const geometry = new THREE.BoxGeometry(1, 1, 100, 100);

        const count = geometry.attributes.position.count;

        const new_position = new Float32Array(count);

        for (let i = 0; i < new_position.length; i++) {
            new_position[i] = Math.random();
        }

        geometry.setAttribute('aRandom', new THREE.BufferAttribute(new_position, 1));

        const plane = new THREE.Mesh(geometry, this.material);

        //plane.rotation.set(1,0,2)

        this.scene.add(plane);

    }

    private setLight() {
        this.scene.add(new THREE.AmbientLight(0xcccccc));
        let light = new THREE.PointLight(0xffffff, 1);
        this.scene.add(light);
        //告诉平行光需要开启阴影投射
        //light.castShadow = true;
        // light.position.y = 20;
        // const light = new THREE.DirectionalLight( 0xffffff, 2 );
        // light.position.set( 20, -50, 20 );
        // light.castShadow = true;
        // light.shadow.mapSize.width = 1024;
        //
        // light.shadow.mapSize.height = 1024;
        // this.scene.add(light);
    }

    private setScene() {
        // 设置场景背景色
        // this.scene!.background = new THREE.Color('skyblue');
    }

    private setRenderer() {
        this.renderer.setClearAlpha(0);
        // this.scene.background = new THREE.CubeTextureLoader().load([
        //     r,l,t,b,f,b2
        // ]);
        // 色调映射
        this.renderer!.toneMapping = THREE.ReinhardToneMapping;
        // 色调曝光度
        this.renderer!.toneMappingExposure = 1.25;
        // 是否开启阴影渲染
        this.renderer!.shadowMap.enabled = true;
        // 阴影类型
        this.renderer!.shadowMap.type = THREE.PCFSoftShadowMap;
        // 输出编码格式
        this.renderer!.outputColorSpace = THREE.SRGBColorSpace;
        // 在renderer里面设置背景色
        this.renderer!.setClearColor(0xffffff, 0);
    }

    private setControls() {
        //使动画循环使用时阻尼或自转 意思是否有惯性
        this.controls.enableDamping = true;
        //动态阻尼系数 就是鼠标拖拽旋转灵敏度
        this.controls.dampingFactor = 0.25;
        //是否可以缩放
        this.controls.enableZoom = true;
        //设置相机距离原点的最远距离
        this.controls.minDistance = 1;
        //设置相机距离原点的最远距离
        this.controls.maxDistance = 200;
        //是否开启右键拖拽
        this.controls.enablePan = false;
    }

    private setCamera() {
        // 设置相机
        this.camera!.position.set(-1, 2.5, 0);
        // 设置观看中心点
        this.camera!.lookAt(0, 0, 0);
    }

    // GUI控制显示
    private setGui() {
        // //声明一个保存需求修改的相关数据的对象
        // let _that = this;
        // let datGui = new GUI();
        // //将设置属性添加到gui当中，gui.add(对象，属性，最小值，最大值）
        // datGui.add(this.GUI_CONFIG, "R", 0, 255);
        // datGui.add(this.GUI_CONFIG, "G", 0, 255);
        // datGui.add(this.GUI_CONFIG, "B", 0, 255);
        // datGui.add(this.GUI_CONFIG, "rotate").onChange(function(val: any) {
        //     _that.controls.autoRotate = val;
        // });
        // datGui.addColor(this.GUI_CONFIG, "lineColor").onChange(function() {
        //     _that.linesGroup!.traverse(function(child: any) {
        //         if (child.isLine)
        //             child.material = new THREE.LineBasicMaterial({
        //                 color: _that.GUI_CONFIG.lineColor
        //             });
        //     });
        // });
        //
        // const bloomFolder = datGui.addFolder('bloom');
        //
        // bloomFolder.add(this.BLOOM_PASS_CONFIG, 'bloomThreshold', 0.0, 1.0).onChange((value: any) => {
        //     this.bloomPass!.threshold = Number(value);
        // })
        //
        // bloomFolder.add(this.BLOOM_PASS_CONFIG, 'bloomStrength', 0.0, 3.0 ).onChange( (value: any) => {
        //     this.bloomPass!.strength = Number( value );
        // } );
        //
        // datGui.add(this.BLOOM_PASS_CONFIG, 'bloomRadius', 0.0, 1.0 ).step( 0.01 ).onChange((value: any) => {
        //     this.bloomPass!.radius = Number(value);
        // });
    }

    // 动态渲染
    private animate() {

        if (this.material) {
            this.controls.update();

            const Delta = this.clock.getDelta();

            this.material.uniforms.u_time.value += Delta;

            this.renderer.render(this.scene, this.camera);

            requestAnimationFrame(this.animate.bind(this));
        }
    }
}